﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MapIdSearch
{
    public class GetMapIDByLonLat
    {
        /// <summary>
        /// 通过当前点的经纬度获取图幅ID,经差，纬差
        /// </summary>
        /// <param name="lon">当前点经度</param>
        /// <param name="lat">当前点纬度</param>
        /// <param name="scaleIndex">比例尺索引[1-1：100万;2-1：50万;3-1：25万;4-1：10万; 5-1：5万;6-1：2.5万;7-1：1万]</param>
        /// <returns>表示图幅ID，经差，纬差的MapIDLonLatDif对象</returns>
        public MapIDLonLatDif GetMapIDLonLatDifByLonLat(double lon,double lat,int scaleIndex) 
        {
            this.i = scaleIndex;
            MapIDLonLatDif mill = new MapIDLonLatDif();
            string tempLonDif = "", tempLatDif = "";
            string tempMapNewID = "", tempMapOldID = "";
            switch (scaleIndex)
            {
                case 1:
                    tempMapNewID = JD_100(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 2:
                    tempMapNewID = JD_50(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 3:
                    tempMapNewID = JD_25(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 4:
                    tempMapNewID = JD_10(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 5:
                    tempMapNewID = JD_5(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 6:
                    tempMapNewID = JD_3(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
                case 7:
                    tempMapNewID = JD_1(lon, lat, ref tempLonDif, ref tempLatDif);
                    break;
            }
            string NewNum = tempMapNewID;
            tempMapOldID = SheetNoConvert(NewNum, ref tempLonDif, ref tempLatDif);
            mill.MapIDNew = tempMapNewID;
            mill.MapIDOld = tempMapOldID;
            mill.LonDif = tempLonDif;
            mill.LatDif = tempLatDif;
            return mill;
        }
        /// <summary>
        /// 比例尺索引
        /// </summary>
        private int i;
        private string ZM(int k)
        {
            string[] s = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V" };
            return s[k - 1];
        }

        /*===============================================================================================================*/
        //由新图幅号转到旧图幅号 
        private string New_Old_50(string bigRowNo, string bigColNo, int H, int L ,ref string lonDif,ref string latDif)        //由新图幅转旧图幅   1 ：50万
        {
            lonDif = "3°";
            latDif = "2°";
            #region 50W
            //if (H > 2 || L > 2)
            //    return null;
            int X = (H - 1) * 2 + (L - 1) + 1;      //旧图幅号对应的地图代码  
            string code = "";
            switch (X)
            {
                case 1:
                    code = "A";
                    break;
                case 2:
                    code = "B";
                    break;
                case 3:
                    code = "C";
                    break;
                case 4:
                    code = "D";
                    break;
                default:
                    break;
            }
            return bigRowNo + "-" + bigColNo + "-" + code;
            #endregion
        }
        private string New_Old_25(string bigRowNo, string bigColNo, int H, int L, ref string lonDif, ref string latDif)        //由新图幅转旧图幅   1 ：25万
        {
            lonDif = "1°30′";
            latDif = "1°";
            #region 25W
            //if (H > 4 || L > 4)
            //  return null;
            int X = (H - 1) * 4 + (L - 1) + 1;      //旧图幅号对应的地图代码  
            string code = "";
            if (X > 9)
                code = X.ToString();
            else code = "0" + X;
            return bigRowNo + "-" + bigColNo + "-[" + code + "]";
            #endregion
        }
        private string New_Old_10(string bigRowNo, string bigColNo, int H, int L, ref string lonDif, ref string latDif)        //由新图幅转旧图幅   1 ：10万
        {
            lonDif = "30′";
            latDif = "20′";
            #region 10W
            //if (H > 12 || L > 12)
            //   return null;
            int X = (H - 1) * 12 + (L - 1) + 1;         //旧图幅号对应的地图代码  
            string code = "";
            if (X > 99)
                code = X.ToString();
            else if (X > 9) code = "0" + X;
            else code = "00" + X;
            return bigRowNo + "-" + bigColNo + "-" + code + "";
            #endregion
        }
        private string New_Old_5(string bigRowNo, string bigColNo, int H, int L, ref string lonDif, ref string latDif)         //由新图幅转旧图幅   1 ： 5万
        {
            lonDif = "15′";
            latDif = "10′";
            #region 5W
            //if (H > 24 || L > 24)
            //   return null;
            int H10 = (H - 1) / 2 + 1;  //10W地形图对应的行号  
            int L10 = (L - 1) / 2 + 1;  //10W地形图对应的列号  
            int X10 = (H10 - 1) * 12 + (L10 - 1) + 1;         //10W旧图幅号对应的地图代码  
            string code = "";
            if (X10 > 99)
                code = X10.ToString();
            else if (X10 > 9) code = "0" + X10;
            else code = "00" + X10;
            int X = (H - 2 * H10 + 1) * 2 + (L - 2 * L10 + 1) + 1;         //旧图幅号对应的地图代码  
            switch (X)
            {
                case 1:
                    code += "-A";
                    break;
                case 2:
                    code += "-B";
                    break;
                case 3:
                    code += "-C";
                    break;
                case 4:
                    code += "-D";
                    break;
                default:
                    break;
            }
            return bigRowNo + "-" + bigColNo + "-" + code + "";
            #endregion
        }
        private string New_Old_3(string bigRowNo, string bigColNo, int H, int L, ref string lonDif, ref string latDif)         //由新图幅转旧图幅   1：2.5万
        {
            lonDif = "7′30″";
            latDif = "5′";
            #region 2.5W
            // if (H > 2 || L > 2)
            //    return null;
            int H10 = (H - 1) / 2 + 1;  //10W地形图对应的行号  
            int L10 = (L - 1) / 2 + 1;  //10W地形图对应的列号  
            int X10 = (H10 - 1) * 12 + (L10 - 1) + 1;         //10W旧图幅号对应的地图代码  
            string code = "";
            if (X10 > 99)
                code = X10.ToString();
            else if (X10 > 9) code = "0" + X10;
            else code = "00" + X10;
            int X = (H - 2 * H10 + 1) * 2 + (L - 2 * L10 + 1) + 1;         //旧图幅号对应的地图代码  
            switch (X)
            {
                case 1:
                    code += "-A";
                    break;
                case 2:
                    code += "-B";
                    break;
                case 3:
                    code += "-C";
                    break;
                case 4:
                    code += "-D";
                    break;
                default:
                    break;
            }
            int H5 = (H - 1) / 2 + 1;  //5W地形图对应的行号  
            int L5 = (L - 1) / 2 + 1;  //5W地形图对应的列号  
            // int X5 = (H5 - 1) * 12 + (L5 - 1) + 1;         //5W旧图幅号对应的地图代码  
            int X1 = (H - 2 * H5 + 1) * 2 + (L - 2 * L5 + 1) + 1;         //旧图幅号对应的地图代码  
            if (X1 > 99)
                code = X1.ToString();
            else if (X1 > 9) code += "-0" + X1;
            else code += "-00" + X1;
            #endregion
            return bigRowNo + "-" + bigColNo + "-" + code;
        }
        private string New_Old_1(string bigRowNo, string bigColNo, int H, int L, ref string lonDif, ref string latDif)         //由新图幅转旧图幅   1 ： 1万
        {
            lonDif = "3′45″";
            latDif = "2′30″";
            #region 1W
            //if (H > 24 || L > 24)
            //    return null;
            int H10 = (H - 1) / 8 + 1;  //10W地形图对应的行号  
            int L10 = (L - 1) / 8 + 1;  //10W地形图对应的列号  
            int X10 = (H10 - 1) * 12 + (L10 - 1) + 1;         //10W旧图幅号对应的地图代码  
            string code = "";
            if (X10 > 99)
                code = X10.ToString();
            else if (X10 > 9) code = "0" + X10;
            else code = "00" + X10;
            //if (H > 2 || L > 2)
            //    return null;
            int X = (H - 2 * H10 + 1) * 2 + (L - 2 * L10 + 1) + 1;         //旧图幅号对应的地图代码  
            if (X > 99)
                code += "-(" + X.ToString();
            else if (X > 9) code += "-(0" + X;
            else code += "-(00" + X;
            return bigRowNo + "-" + bigColNo + "-" + code + ")";
            #endregion
        }

        private string SheetNoConvert(string num1, ref string lonDif, ref string latDif)                                   //由新图幅号转到旧图幅号主体函数
        {
            if (num1.Length != 3 && num1.Length != 10) return null;               //.Length != 3 &&    .Length != 10) return null;
            string bigRowNo = num1[0].ToString();                     //NewNo[0].ToString();
            string bigColNo = num1.Substring(1, 2);                                         //NewNo.Substring(1, 2);

            if (i == 1)   //100W  
            {
                lonDif = "4°";
                latDif = "6°";
                return bigRowNo + "-" + bigColNo;
            }
            else
            {
                string Blc = num1.Substring(3, 1);
                int H, L;                       //新图幅号的行列代码，H为行代码，L为列代码  
                if (!int.TryParse(num1.Substring(4, 3), out H) || !int.TryParse(num1.Substring(7, 3), out L))
                    return null;
                if (i == 2)    //50W  
                {
                    if (Blc != "B")
                        return "";
                    return New_Old_50(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else if (i == 3)   //25W  
                {
                    if (Blc != "C")
                        return "";
                    return New_Old_25(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else if (i == 4)    //10W
                {
                    if (Blc != "D")
                        return "";
                    return New_Old_10(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else if (i == 5)    //5W  
                {
                    if (Blc != "E")
                        return "";
                    return New_Old_5(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else if (i == 6)    //2.5W
                {
                    if (Blc != "F")
                        return "";
                    return New_Old_3(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else if (i == 7)    //1W  
                {
                    if (Blc != "G")
                        return "";
                    return New_Old_1(bigRowNo, bigColNo, H, L, ref lonDif, ref latDif);
                }
                else return null;       //图幅号格式不正确  
            }
        }

        /*===============================================================================================================*/
        //由旧图幅号转到新图幅号  
        private string Old_New_50(string[] temp, ref string lonDif, ref string latDif)                                         //由旧图幅转新图幅  1 ： 50万
        {
            lonDif = "2°";
            latDif = "4°";
            #region 50w
            int x50 = -1;
            if (temp[2] == "A")
                x50 = 1;
            else if (temp[2] == "B")
                x50 = 2;
            else if (temp[2] == "C")
                x50 = 3;
            else if (temp[2] == "D")
                x50 = 4;
            else return "";
            int h50 = (x50 - 1) / 2 + 1;
            int l50 = (x50 + 1) % 2 + 1;
            string h50s = "";
            if (h50 < 10)
                h50s = "00" + h50;
            else if (h50 < 100)
                h50s = "0" + h50;
            else h50s = h50.ToString();
            string l50s = "";
            if (l50 < 10)
                l50s = "00" + l50;
            else if (l50 < 100)
                l50s = "0" + l50;
            else l50s = l50.ToString();
            return temp[0] + temp[1] + "B" + h50s + l50s;
            #endregion

        }
        private string Old_New_25(string[] temp, ref string lonDif, ref string latDif)                                         //由旧图幅转新图幅  1 ： 25万
        {
            lonDif = "1°30′";
            latDif = "1°";
            #region 25w
            if (temp[2][0] != '[' || temp[2][3] != ']')
                return "";
            int x25 = -1;
            if (!int.TryParse(temp[2].Substring(1, 2), out x25))
                return "";
            int h25 = (x25 - 1) / 4 + 1;
            int l25 = (x25 + 3) % 4 + 1;
            string h25s = "";
            if (h25 < 10)
                h25s = "00" + h25;
            else if (h25 < 100)
                h25s = "0" + h25;
            else h25s = h25.ToString();
            string l25s = "";
            if (l25 < 10)
                l25s = "00" + l25;
            else if (l25 < 100)
                l25s = "0" + l25;
            else l25s = l25.ToString();
            return temp[0] + temp[1] + "C" + h25s + l25s;
            #endregion
        }
        private string Old_New_10(string[] temp, ref string lonDif, ref string latDif)                                         //由旧图幅转新图幅  1 ： 10万
        {
            lonDif = "30′";
            latDif = "20′";
            #region 10w
            int x10 = -1;
            if (!int.TryParse(temp[2], out x10))
                return "";
            int h10 = (x10 - 1) / 12 + 1;
            int l10 = (x10 + 11) % 12 + 1;
            string h10s = "";
            if (h10 < 10)
                h10s = "00" + h10;
            else if (h10 < 100)
                h10s = "0" + h10;
            else h10s = h10.ToString();
            string l10s = "";
            if (l10 < 10)
                l10s = "00" + l10;
            else if (l10 < 100)
                l10s = "0" + l10;
            else l10s = l10.ToString();
            return temp[0] + temp[1] + "D" + h10s + l10s;
            #endregion
        }
        private string Old_New_5(string[] temp, ref string lonDif, ref string latDif)                                          //由旧图幅转新图幅  1 ：  5万
        {
            lonDif = "15′";
            latDif = "10′";
            #region 5w
            int x10 = -1;
            if (!int.TryParse(temp[2], out x10))
                return "";
            int x5 = -1;
            if (temp[3] == "A")
                x5 = 1;
            else if (temp[3] == "B")
                x5 = 2;
            else if (temp[3] == "C")
                x5 = 3;
            else if (temp[3] == "D")
                x5 = 4;
            else return "";
            int h10 = (x10 - 1) / 12 + 1;
            int l10 = (x10 + 11) % 12 + 1;
            int h5 = 2 * h10 + (x5 - 1) / 2 - 1;
            int l5 = 2 * l10 + (x5 + 1) % 2 - 1;
            string h5s = "";
            if (h5 < 10)
                h5s = "00" + h5;
            else if (h5 < 100)
                h5s = "0" + h5;
            else h5s = h5.ToString();
            string l5s = "";
            if (l5 < 10)
                l5s = "00" + l5;
            else if (l5 < 100)
                l5s = "0" + l5;
            else l5s = l5.ToString();
            return temp[0] + temp[1] + "E" + h5s + l5s;
            #endregion
        }
        private string Old_New_3(string[] temp, ref string lonDif, ref string latDif)                                          //由旧图幅转新图幅  1 ：2.5万
        {
            lonDif = "7′30″";
            latDif = "5′";
            #region  2.5w
            int x10 = -1, x5 = -1, x2 = -1;
            if (!int.TryParse(temp[2], out x10))
                return "";
            int h10 = (x10 - 1) / 12 + 1;
            int l10 = (x10 + 11) % 12 + 1;
            if (temp[3] == "A")
                x5 = 1;
            else if (temp[3] == "B")
                x5 = 2;
            else if (temp[3] == "C")
                x5 = 3;
            else if (temp[3] == "D")
                x5 = 4;
            else return "";
            if (!int.TryParse(temp[4], out x2))
                return "";
            int h5 = 2 * h10 + (x5 - 1) / 2 - 1;
            int l5 = 2 * l10 + (x5 + 1) % 2 - 1;
            int h2 = 2 * h5 + (x2 - 1) / 2 - 1;
            int l2 = 2 * l5 + (x2 + 1) % 2 - 1;
            string h2s = "";
            if (h2 < 10)
                h2s = "00" + h2;
            else if (h2 < 100)
                h2s = "0" + h2;
            else h2s = h2.ToString();
            string l2s = "";
            if (l2 < 10)
                l2s = "00" + l2;
            else if (l2 < 100)
                l2s = "0" + l2;
            else l2s = l2.ToString();
            return temp[0] + temp[1] + "F" + h2s + l2s;
            #endregion
        }
        private string Old_New_1(string[] temp, ref string lonDif, ref string latDif)                                          //由旧图幅转新图幅  1 ：  1万
        {
            lonDif = "3′45″";
            latDif = "2′30″";
            #region  1w
            int x10 = -1, x1 = -1;
            if (!int.TryParse(temp[2], out x10))
                return "";
            if (temp[3][0] != '(' || temp[3][4] != ')')
                return "";
            if (!int.TryParse(temp[3].Substring(1, 3), out x1))
                return "";
            int h10 = (x10 - 1) / 12 + 1;
            int l10 = (x10 + 11) % 12 + 1;
            int h1 = 8 * (h10 - 1) + (x1 - 1) / 8 + 1;
            int l1 = 8 * (l10 - 1) + (x1 + 7) % 8 + 1;
            string h1s = "";
            if (h1 < 10)
                h1s = "00" + h1;
            else if (h1 < 100)
                h1s = "0" + h1;
            else h1s = h1.ToString();
            string l1s = "";
            if (l1 < 10)
                l1s = "00" + l1;
            else if (l1 < 100)
                l1s = "0" + l1;
            else l1s = l1.ToString();
            return temp[0] + temp[1] + "G" + h1s + l1s;
            #endregion
        }

        private string SheetNoConvert2(string old_number, ref string lonDif, ref string latDif)                             //由旧图幅号转到新图幅号主体函数
        {
            String[] temp1 = old_number.Split('-');
            if (temp1.Length == 1) return "";
            else if (i == 1)    //100w
                return temp1[0] + temp1[1];
            else if (i == 2)  //50w
                return Old_New_50(temp1, ref lonDif, ref latDif);
            else if (i == 3)  //25w
                return Old_New_25(temp1, ref lonDif, ref latDif);
            else if (i == 4)  //10w
                return Old_New_10(temp1, ref lonDif, ref latDif);
            else if (i == 5)  //5w
                return Old_New_5(temp1, ref lonDif, ref latDif);
            else if (i == 6)  //2.5w
                return Old_New_3(temp1, ref lonDif, ref latDif);
            else if (i == 7)  //1w
                return Old_New_1(temp1, ref lonDif, ref latDif);
            else return "";
        }

        /*===============================================================================================================*/
        //由所查的地图的左下角经纬度转换为图幅编号
        private string JD_100(double jd100, double wd100, ref string lonDif, ref string latDif)
        {
            lonDif = "6°";
            latDif = "4°";
            int h101 = (int)wd100 / 4 + 1;
            int l101 = (int)jd100 / 6 + 31;
            string hs = ZM(h101);
            return hs + "" + l101;
        }
        private string JD_50(double jd50, double wd50, ref string lonDif, ref string latDif)
        {
            lonDif = "3°";
            latDif = "2°";
            int h501 = (int)wd50 / 4 + 1;
            int l501 = (int)jd50 / 6 + 31;
            int h1 = (4 / 2 - (int)(wd50 % 4) / 2);
            int l1 = (int)((jd50 % 6) / 3) + 1;
            string code = "";
            if (h1 < 9)
                code = "00" + h1;
            else if (h1 < 99)
                code = "0" + h1;
            else code = "" + h1;
            if (l1 < 9)
                code += "00" + l1;
            else if (l1 < 99)
                code += "0" + l1;
            else code += "" + l1;
            string hs = ZM(h501);
            return hs + "" + l501 + "B" + code;
        }
        private string JD_25(double jd25, double wd25, ref string lonDif, ref string latDif)
        {
            lonDif = "1°30′";
            latDif = "1°";
            int h251 = (int)wd25 / 4 + 1;
            int l251 = (int)jd25 / 6 + 31;
            int h25 = (4 / 1 - (int)(wd25 % 4) / 1);
            int l25 = (int)((jd25 % 6) / 1.5) + 1;
            string code = "";
            if (h25 < 9)
                code = "00" + h25;
            else if (h25 < 99)
                code = "0" + h25;
            else code = "" + h25;
            if (l25 < 9)
                code += "00" + l25;
            else if (l25 < 99)
                code += "0" + l25;
            else code += "" + l25;
            string h25s = ZM(h251);
            return h25s + "" + l251 + "C" + code;
        }
        private string JD_10(double jd10, double wd10, ref string lonDif, ref string latDif)
        {
            lonDif = "30′";
            latDif = "20′";
            int h101 = (int)wd10 / 4 + 1;
            int l101 = (int)jd10 / 6 + 31;
            int h10 = (int)((4 / 20) * 60 - (int)(wd10 % 4) / 20 * 60);
            int l10 = (int)((jd10 % 6) / 0.5) + 1;
            string code = "";
            if (h10 < 9)
                code = "00" + h10;
            else if (h10 < 99)
                code = "0" + h10;
            else code = "" + h10;
            if (l10 < 9)
                code += "00" + l10;
            else if (l10 < 99)
                code += "0" + l10;
            else code += "" + l10;
            string h10s = ZM(h101);
            return h10s + "" + l101 + "D" + code;
        }
        private string JD_5(double jd5, double wd5, ref string lonDif, ref string latDif)
        {
            lonDif = "15′";
            latDif = "10′";
            int h55 = (int)wd5 / 4 + 1;
            int l55 = (int)jd5 / 6 + 31;
            int h5 = (int)(4 / 10 * 60 - (int)(wd5 % 4) / 10 * 60);
            int l5 = (int)((jd5 % 6) / 0.25) + 1;
            string code = "";
            if (h5 < 9)
                code = "00" + h5;
            else if (h5 < 99)
                code = "0" + h5;
            else code = "" + h5;
            if (l5 < 9)
                code += "00" + l5;
            else if (l5 < 99)
                code += "0" + l5;
            else code += "" + l5;
            string h5s = ZM(h55);
            return h5s + "" + l55 + "E" + code;
        }
        private string JD_3(double jd3, double wd3, ref string lonDif, ref string latDif)
        {
            lonDif = "7′30″";
            latDif = "5′";
            int h33 = (int)wd3 / 4 + 1;
            int l33 = (int)jd3 / 6 + 31;
            int h3 = (int)(4 * 60 / 5 - (int)(wd3 % 4) / 5 * 60);
            int l3 = (int)((int)(jd3 % 6) / 0.125) + 1;
            string code = "";
            if (h3 < 9)
                code = "00" + h3;
            else if (h3 < 99)
                code = "0" + h3;
            else code = "" + h3;
            if (l3 < 9)
                code += "00" + l3;
            else if (l3 < 99)
                code += "0" + l3;
            else code += "" + l3;
            string h3s = ZM(h33);
            return h3s + "" + l33 + "F" + code;
        }
        private string JD_1(double jd1, double wd1, ref string lonDif, ref string latDif)
        {
            lonDif = "3′45″";
            latDif = "2′30″";
            int h11 = (int)wd1 / 4 + 1;
            int l11 = (int)jd1 / 6 + 31;
            int h1 = (int)(4 / 2.5 * 60 - (int)(wd1 % 4) / 2.5 * 60);
            int l1 = (int)((jd1 % 6) / 0.0625) + 1;
            string code = "";
            if (h1 < 9)
                code = "00" + h1;
            else if (h1 < 99)
                code = "0" + h1;
            else code = "" + h1;
            if (l1 < 9)
                code += "00" + l1;
            else if (l1 < 99)
                code += "0" + l1;
            else code += "" + l1;
            string h1s = ZM(h11);
            return h1s + "" + l11 + "G" + code;
        }

    }

    /// <summary>
    /// 图幅新旧ID，经差，纬差
    /// </summary>
    public struct MapIDLonLatDif 
    {
        /// <summary>
        /// 新图幅ID
        /// </summary>
        public string MapIDNew;
        /// <summary>
        /// 旧图幅ID
        /// </summary>
        public string MapIDOld;
        /// <summary>
        /// 经差
        /// </summary>
        public string LonDif;
        /// <summary>
        /// 纬差
        /// </summary>
        public string LatDif;
    }
}
